package com.bsoft.gol.hcs.specialist.service.impl;

import com.alibaba.fastjson.JSONObject;
import ctd.controller.exception.ControllerException;
import ctd.dictionary.Dictionary;
import ctd.dictionary.DictionaryItem;
import ctd.dictionary.controller.DictionaryController;
import ctd.dictionary.entity.DictionaryCategoryEntity;
import ctd.dictionary.entity.DictionaryItemEntity;
import ctd.net.rpc.json.JSONResponseBean;
import ctd.net.rpc.util.ServiceAdapter;
import ctd.spring.boot.annotation.SsdevReference;
import ctd.spring.boot.annotation.SsdevService;
import ctd.util.KeyGenerator;
import ctd.util.WBConverter;
import ctd.util.annotation.RpcService;
import ctd.util.context.ContextUtils;
import com.bsoft.gol.hcs.enumcase.CrucialIndexCategoryEnum;
import com.bsoft.gol.hcs.enumcase.CrucialIndexEnum;
import com.bsoft.gol.hcs.enumcase.CrucialTypeEnum;
import com.bsoft.gol.hcs.enumcase.InspectIndexEnum;
import hcn.base.Organization;
import hcn.util.BaseResponse;
import hcn.bean.UserAllVo;
import com.bsoft.gol.hcs.his.bean.crucial.request.QueryCrucialRecordRequest;
import com.bsoft.gol.hcs.his.bean.crucial.response.*;
import com.bsoft.gol.hcs.his.service.ICrucialHisService;
import com.bsoft.gol.hcs.his.service.IIndexHisService;
import opensource.jpinyin.PinyinHelper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import pcn.service.web.BaseDeviceService;
import service.rpc.impl.OrganizationRpcServiceImpl;
import com.bsoft.gol.hcs.specialist.bean.request.*;
import com.bsoft.gol.hcs.specialist.bean.response.*;
import com.bsoft.gol.hcs.specialist.dao.DiseaseSpeciesRelateDAO;
import com.bsoft.gol.hcs.specialist.dao.FusBaseDictionaryDAO;
import com.bsoft.gol.hcs.specialist.dao.FusCrucialIndexRecordDAO;
import com.bsoft.gol.hcs.specialist.dao.FusIndexResultDAO;
import com.bsoft.gol.hcs.specialist.entity.FusCrucialIndexRecord;
import com.bsoft.gol.hcs.specialist.entity.FusIndexResult;
import com.bsoft.gol.hcs.specialist.service.ICrucialIndexService;
import com.bsoft.gol.hcs.utils.CommonUtils;
import com.bsoft.gol.hcs.utils.Constants;
import com.bsoft.gol.hcs.utils.Utils;
import org.atag.util.common.RedisUtil;
import org.atag.util.common.SpringPropertiesUtil;

import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 关联指标服务层
 * @Author: zhaorb
 * @Date: 2020/7/20 14:35
 **/
@SsdevService("crucialIndex")
public class CrucialIndexImpl implements ICrucialIndexService {
    private static final Logger log = LoggerFactory.getLogger(CrucialIndexImpl.class);

    @Autowired
    FusCrucialIndexRecordDAO fusCrucialIndexRecordDAO;
    @Autowired
    FusIndexResultDAO fusIndexResultDAO;
    @Autowired
    IIndexHisService indexHisService;
    @Autowired
    FusBaseDictionaryDAO fusBaseDictionaryDAO;
    @Autowired
    DiseaseSpeciesRelateDAO diseaseSpeciesRelateDAO;
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    private ICrucialHisService crucialHisService;
    @SsdevReference("hcn.baseDeviceService")
    private BaseDeviceService baseDeviceService;
    @Autowired
    private OrganizationRpcServiceImpl organizationRpcService;

    /**
     * @Description: 查询关联指标信息
     * @Author: zhaorb
     * @Date: 2020/7/20 14:17
     **/
    @Override
    @RpcService
    public CrucialIndexTotalResponse queryCrucialIndex(QueryCrucialIndexRequest request) throws ControllerException {
        CrucialIndexTotalResponse totalResponse = new CrucialIndexTotalResponse();
        if (CommonUtils.isEmpty(request) || CommonUtils.isEmpty(request.getOrganizationList())) {
            return totalResponse;
        }
        List<FusCrucialIndexRecord> records = fusCrucialIndexRecordDAO.queryFusCrucialIndexRecordList(request);
        BigInteger total = fusCrucialIndexRecordDAO.queryFusCrucialIndexRecordTotal(request);
        totalResponse.setList(queryCrucialIndexRecords(records));
        totalResponse.setTotal(total);
        return totalResponse;
    }

    /**
     * 按照类型查询关联指标信息
     *
     * @param request
     * @return
     * @throws ControllerException
     */
    @Override
    @RpcService
    public CrucialIndexRecordsResponse queryCrucialIndexByType(QueryCrucialIndexRequest request) throws ControllerException {
        List<CrucialIndexResponse> crucialList = new ArrayList<>();
        CrucialIndexRecordsResponse response = new CrucialIndexRecordsResponse();
        try {
            //手动设置查询启用的关联指标
            request.setIndexStatus("1");
            List<FusCrucialIndexUnionResultRecordsResp> records = fusCrucialIndexRecordDAO.queryCrucialIndexUnionResultRecords(request);
            if (CommonUtils.isNotEmpty(records)) {
                Map<String, List<FusCrucialIndexUnionResultRecordsResp>> crucialMap = records.stream().collect(Collectors.groupingBy(record -> record.getIndexId()));
                for (String cKey : crucialMap.keySet()) {
                    CrucialIndexResponse crucialIndexResponse = new CrucialIndexResponse();
                    FusCrucialIndexUnionResultRecordsResp recordsResp = crucialMap.get(cKey).get(0);
                    BeanUtils.copyProperties(recordsResp, crucialIndexResponse);
                    List<FusIndexResult> crucialResult = crucialMap.get(cKey).stream().map(crucial -> {
                        FusIndexResult fusIndexResult = new FusIndexResult();
                        BeanUtils.copyProperties(crucial, fusIndexResult);
                        return fusIndexResult;
                    }).collect(Collectors.toList());
                    crucialIndexResponse.setIndexResultList(crucialResult);
                    crucialList.add(crucialIndexResponse);
                }
            } else {
                return response;
            }
            response = handleCrucialType(crucialList);
            return response;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ControllerException("查询关联指标信息失败");
        }
    }

    /**
     * 根据分类获取指标信息
     *
     * @param request
     * @return
     * @throws ControllerException
     */
    @RpcService
    @Override
    public Map<String, List<CrucialIndexClassifyRecordResponse>> queryCrucialIndexByClassifyId(QueryCrucialIndexRequest request) throws ControllerException {
        Map<String, List<CrucialIndexClassifyRecordResponse>> resultMap = new HashMap<>();
        QueryCrucialIndexRequest indexRequest = new QueryCrucialIndexRequest();
        BeanUtils.copyProperties(request, indexRequest);
        //1.按照指标类型获取分类信息
        try {
            String tenantId = (String) ContextUtils.get("$tenantId");
            //检验
            List<CrucialIndexClassifyRecordResponse> inspectResponse = dealCrucialIndexRecords(CrucialTypeEnum.INSPECT.getType(), CrucialIndexEnum.CRUCIAL_INSPECT_TYPE.getId() + "@" + tenantId, request);
            //检查
            List<CrucialIndexClassifyRecordResponse> examResponse = dealCrucialIndexRecords(CrucialTypeEnum.EXAM.getType(), CrucialIndexEnum.CRUCIAL_CHECK_TYPE.getId() + "@" + tenantId, request);
            //TODO 体征无分类，直接获取指标信息
            List<CrucialIndexClassifyRecordResponse> signResponse = dealCrucialIndexRecordList(CrucialTypeEnum.SIGN.getType(), indexRequest);
            //TODO 病理无分类，直接获取指标信息
            List<CrucialIndexClassifyRecordResponse> pathologyResponse = dealCrucialIndexRecordList(CrucialTypeEnum.PATHOLOGY.getType(), indexRequest);
            resultMap.put(CrucialIndexEnum.CRUCIAL_INSPECT_TYPE.getCode(), inspectResponse);
            resultMap.put(CrucialIndexEnum.CRUCIAL_CHECK_TYPE.getCode(), examResponse);
            resultMap.put(CrucialIndexCategoryEnum.SIGN_CRUCIAL.getCode(), signResponse);
            resultMap.put(CrucialIndexCategoryEnum.PATHOLOGY.getCode(), pathologyResponse);
            return resultMap;
        } catch (
                Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据检验检查分类，获取指标数据
     *
     * @param indexType
     * @param dicName
     * @param request
     * @return
     * @throws ControllerException
     */
    private List<CrucialIndexClassifyRecordResponse> dealCrucialIndexRecords(String indexType, String dicName, QueryCrucialIndexRequest request) throws ControllerException {
        List<CrucialIndexClassifyRecordResponse> responses = new ArrayList<>();
        Dictionary dictionary = DictionaryController.instance().get(dicName);
        List<DictionaryItem> dicItems = dictionary.getSlice(null, 0, null);
        request.setIndexType(indexType);
        if (CommonUtils.isNotEmpty(dicItems)) {
            //检查检验的处理方式
            if (CrucialTypeEnum.INSPECT.getType().equals(indexType) || CrucialTypeEnum.EXAM.getType().equals(indexType)) {
                for (DictionaryItem item : dicItems) {
                    CrucialIndexClassifyRecordResponse crucialIndexClassifyRecord = new CrucialIndexClassifyRecordResponse();
                    request.setIndexClassifyId(item.getKey());
                    CrucialIndexRecordsResponse crucialIndexRecordsResponse = queryCrucialIndexByType(request);
                    crucialIndexClassifyRecord.setIndexId(item.getKey());
                    crucialIndexClassifyRecord.setIndexName(item.getText());
                    if (CrucialTypeEnum.INSPECT.getType().equals(indexType)) {
                        crucialIndexClassifyRecord.setChildren(crucialIndexRecordsResponse.getInspectCrucialIndexList());
                    } else if (CrucialTypeEnum.EXAM.getType().equals(indexType)) {
                        crucialIndexClassifyRecord.setChildren(crucialIndexRecordsResponse.getCheckCrucialIndexList());
                    }
                    responses.add(crucialIndexClassifyRecord);
                }
            }

        }
        return responses;
    }

    /**
     * 处理体征和病理指标数据
     *
     * @param indexType
     * @param request
     * @return
     * @throws ControllerException
     */
    public List<CrucialIndexClassifyRecordResponse> dealCrucialIndexRecordList(String indexType, QueryCrucialIndexRequest request) throws ControllerException {
        List<CrucialIndexClassifyRecordResponse> responses = new ArrayList<>();
        request.setIndexType(indexType);
        CrucialIndexClassifyRecordResponse crucialIndexClassifyRecord = new CrucialIndexClassifyRecordResponse();
        //只查询启用的指标
        request.setIndexStatus("1");
        List<FusCrucialIndexRecord> fusCrucialIndexRecords = fusCrucialIndexRecordDAO.queryFusCrucialIndexAllRecordList(request);
        List<CrucialIndexResponse> crucialIndexResponses = queryCrucialIndexRecords(fusCrucialIndexRecords);
        crucialIndexClassifyRecord.setChildren(crucialIndexResponses);
        responses.add(crucialIndexClassifyRecord);
        return responses;
    }

    /**
     * 处理根据类型返回关联指标
     *
     * @param crucialIndexResponses
     * @return
     */
    private CrucialIndexRecordsResponse handleCrucialType(List<CrucialIndexResponse> crucialIndexResponses) {
        CrucialIndexRecordsResponse crucialList = new CrucialIndexRecordsResponse();
        List<CrucialIndexResponse> inspectCrucialIndexList = crucialIndexResponses.
                stream().filter(c -> CrucialTypeEnum.INSPECT.getType().equals(c.getIndexType())).collect(Collectors.toList());
        //检查只显示设置的默认内置指标
        List<CrucialIndexResponse> checkCrucialIndexList = crucialIndexResponses.
                stream().filter(c -> CrucialTypeEnum.EXAM.getType().equals(c.getIndexType())).collect(Collectors.toList());
        List<CrucialIndexResponse> signCrucialIndexList = crucialIndexResponses.
                stream().filter(c -> CrucialTypeEnum.SIGN.getType().equals(c.getIndexType())).collect(Collectors.toList());
        List<CrucialIndexResponse> pathologyCrucialIndexList = crucialIndexResponses.
                stream().filter(c -> CrucialTypeEnum.PATHOLOGY.getType().equals(c.getIndexType())).collect(Collectors.toList());
        crucialList.setInspectCrucialIndexList(inspectCrucialIndexList);
        crucialList.setCheckCrucialIndexList(checkCrucialIndexList);
        crucialList.setSignCrucialIndexList(signCrucialIndexList);
        crucialList.setPathologyCrucialIndexList(pathologyCrucialIndexList);
        return crucialList;
    }

    /**
     * 处理关联指标信息获取
     *
     * @param records
     */
    private List<CrucialIndexResponse> queryCrucialIndexRecords(List<FusCrucialIndexRecord> records) {
        List<CrucialIndexResponse> list = new ArrayList<>();
        if (CommonUtils.isNotEmpty(records)) {
            list = records.stream().map((record) -> {
                List<FusIndexResult> results = fusIndexResultDAO.queryFusIndexResultList(record.getIndexId());
                CrucialIndexResponse response = new CrucialIndexResponse();
                BeanUtils.copyProperties(record, response);
                response.setIndexResultList(results);
                String indexResultName = "";
                String indexResultType = "";
                if (CommonUtils.isNotEmpty(results)) {
                    for (FusIndexResult result : results) {
                        indexResultName = result.getIndexResultName();
                        indexResultType = result.getIndexResultType();
                    }
                }
                response.setIndexResultName(indexResultName);
                response.setIndexResultType(indexResultType);
                return response;
            }).collect(Collectors.toList());
        }
        return list;
    }

    /**
     * @Description: 新增关联指标信息
     * @Author: zhaorb
     * @Date: 2020/7/20 14:17
     **/
    @Override
    @RpcService
    public Integer addCrucialIndex(CrucialIndexReq request) throws ControllerException {
        UserAllVo userVo = baseDeviceService.getAllByOnline();
        if (CommonUtils.isEmpty(request.getIndexId())) {
            try {
                log.info("FlowInvestigationService addCrucialIndex 进入 {}", request.toString());
                FusCrucialIndexRecord record = new FusCrucialIndexRecord();
                BeanUtils.copyProperties(request, record);
                if (CommonUtils.isEmpty(record.getIndexStatus())) {
                    record.setIndexStatus("1");
                }
                //判断必填项
                //根据类型判断必填项
                String indexType = request.getIndexType();
                if (CommonUtils.isNotEmpty(indexType)) {
                    if (CrucialTypeEnum.INSPECT.getType().equals(indexType) || CrucialTypeEnum.EXAM.getType().equals(indexType)) {
                        if (!StringUtils.isNoneEmpty(request.getIndexCode(), request.getIndexClassifyId(), request.getIndexName())) {
                            throw new ControllerException("参数错误");
                        }
                    } else {
                        if (!StringUtils.isNoneEmpty(request.getIndexCode(), request.getIndexName())) {
                            throw new ControllerException("参数错误");
                        }
                    }
                } else {
                    throw new ControllerException("指标类型不能为空");
                }

                //指标编码是否重复
                FusCrucialIndexRecord fusCrucialIndexRecordByIndexCode = fusCrucialIndexRecordDAO.getFusCrucialIndexRecordByIndexCode(request.getIndexCode());
                if (CommonUtils.isNotEmpty(fusCrucialIndexRecordByIndexCode)) {
                    throw new ControllerException("指标编码已存在");
                }
                if (CommonUtils.isNotEmpty(request.getIndexName())) {
                    String shortPinyin = PinyinHelper.getShortPinyin(request.getIndexName());
                    record.setPinyinCode(shortPinyin);
                }
                record.setIndexId(Utils.getUUID());
                record.setCreateTime(new Date());
                record.setModifyDt(new Date());
                fusCrucialIndexRecordDAO.save(record);
                List<FusIndexResult> results = request.getIndexResultList();
                if (CommonUtils.isNotEmpty(results)) {
                    for (FusIndexResult indexResult : results) {
                        indexResult.setIndexResultId(Utils.getUUID());
                        indexResult.setIndexId(record.getIndexId());
                        indexResult.setAgeLimitUnion(indexResult.getAgeLowerLimit() + "-" + indexResult.getAgeUpperLimit());
                        indexResult.setCreateTime(new Timestamp(System.currentTimeMillis()));
                        fusIndexResultDAO.save(indexResult);
                    }
                }
                return results.size();
            } catch (Exception e) {
                e.printStackTrace();
                throw new ControllerException("新增指标失败： " + e.getMessage());
            }
        } else {
            try {
                if (CommonUtils.isNotEmpty(request.getIndexId())) {
                    FusCrucialIndexRecord record = fusCrucialIndexRecordDAO.getFusCrucialIndexRecordByKey(request.getIndexId());
                    if (CommonUtils.isNotEmpty(record)) {
                        record.setIndexName(request.getIndexName());
                        record.setOrganizationId(request.getOrganizationId());
                        record.setOrganizationName(request.getOrganizationName());
                        record.setIndexClassifyId(request.getIndexClassifyId());
                        record.setIndexClassifyName(request.getIndexClassifyName());
                        record.setIndexCode(request.getIndexCode());
                        record.setIndexAbbreviation(request.getIndexAbbreviation());
                        record.setSampleType(request.getSampleType());
                        record.setUnit(request.getUnit());
                        record.setDescription(request.getDescription());
                        record.setSignificantDigits(request.getSignificantDigits());
                        record.setIndexResultType(request.getIndexResultType());
                        record.setIndexResultName(request.getIndexResultName());
                        //判断是否是禁用当前指标，需判断当前指标是否在使用中
                        if (!record.getIndexStatus().equals(request.getIndexStatus())) {
                            //判断指标是否在使用中
                            Long count = diseaseSpeciesRelateDAO.getCountByIndexId(request.getIndexId());
                            if (count == null || count < 1L) {
                                record.setIndexStatus(request.getIndexStatus());
                            } else {
                                throw new ControllerException("该关联指标信息已经在使用中");
                            }
                        }
                        record.setModifyId(userVo.getUserId());
                        record.setModifyUsername(userVo.getUserName());
                        record.setModifyDt(new Date());
                        fusCrucialIndexRecordDAO.update(record);
                        fusIndexResultDAO.deleteFusIndexResultIndexId(request.getIndexId());
                        List<FusIndexResult> results = request.getIndexResultList();
                        if (CommonUtils.isNotEmpty(results)) {
                            for (FusIndexResult indexResult : results) {
                                indexResult.setIndexId(request.getIndexId());
                                indexResult.setAgeLimitUnion(indexResult.getAgeLowerLimit() + "-" + indexResult.getAgeUpperLimit());
                                indexResult.setCreateTime(new Date());
                                indexResult.setIndexResultId(Utils.getUUID());
                                fusIndexResultDAO.save(indexResult);
                            }
                        }
                    }
                } else {
                    throw new ControllerException("关联指标id不能为空");
                }
                return 1;
            } catch (Exception e) {
                e.printStackTrace();
                throw new ControllerException("编辑失败" + e.getMessage());
            }
        }
    }


    /**
     * excel导入数据保存
     *
     * @param record
     * @throws ControllerException
     */
    @RpcService
    @Override
    public void addCrucialIndexRecord(String record) throws ControllerException {
        try {
            CrucialIndexImportResponse crucialIndexImport = JSONObject.parseObject(record, CrucialIndexImportResponse.class);
            //查询分类是否存在，不存在则导入失败
            String tenantId = (String) ContextUtils.get("$tenantId");
            String id = CrucialIndexEnum.CRUCIAL_INSPECT_TYPE.getId();
            if (CommonUtils.isEmpty(tenantId)) {
                tenantId = SpringPropertiesUtil.get("tenantId");
            }
            Dictionary dic = DictionaryController.instance().get(id + "@" + tenantId);
            DictionaryItem item = dic.getItem(crucialIndexImport.getIndexClassifyId());
            if (CommonUtils.isEmpty(item)) {
                throw new ControllerException("导入失败检验指标分类不存在");
            }
            String indexId = UUID.randomUUID().toString().replace("-", "");
            FusCrucialIndexRecord fusCrucialIndexRecord = new FusCrucialIndexRecord();
            BeanUtils.copyProperties(crucialIndexImport, fusCrucialIndexRecord);
            fusCrucialIndexRecord.setIndexId(indexId);
            fusCrucialIndexRecord.setPinyinCode(PinyinHelper.getShortPinyin(crucialIndexImport.getIndexName()));
            fusCrucialIndexRecord.setCreateTime(new Date());
            fusCrucialIndexRecord.setIndexStatus(crucialIndexImport.getStatus());
            fusCrucialIndexRecordDAO.save(fusCrucialIndexRecord);
            FusIndexResult fusIndexResult = new FusIndexResult();
            fusIndexResult.setIndexResultId(KeyGenerator.randomGenerate());
            fusIndexResult.setIndexId(indexId);
            fusIndexResult.setSampleType(fusCrucialIndexRecord.getSampleType());
            fusIndexResult.setSampleName(fusCrucialIndexRecord.getSampleName());
            fusIndexResult.setIndexResultType(crucialIndexImport.getIndexResultType());
            fusIndexResult.setIndexResultName(crucialIndexImport.getIndexResultValue());
            fusIndexResult.setGender("1");
            fusIndexResultDAO.save(fusIndexResult);
            FusIndexResult fusIndexResult2 = new FusIndexResult();
            BeanUtils.copyProperties(fusIndexResult, fusIndexResult2);
            fusIndexResult2.setIndexResultId(KeyGenerator.randomGenerate());
            fusIndexResult2.setIndexId(indexId);
            fusIndexResult.setGender("2");
            fusIndexResultDAO.save(fusIndexResult2);
        } catch (Exception e) {
            log.info("保存同步关联指标数据失败: {}", e.getMessage());
            throw new ControllerException("保存同步关联指标数据失败: " + e.getMessage());
        }
    }

    /**
     * @Description: 删除关联指标信息
     * @Author: zhaorb
     * @Date: 2020/7/20 14:17
     **/
    @Override
    @RpcService
    public void deleteCrucialIndex(DeleteCrucialIndexRequest request) throws ControllerException {
        log.info("FlowInvestigationService deleteCrucialIndex 进入 {}", request.toString());
        if (CommonUtils.isNotEmpty(request.getIndexId())) {
            FusCrucialIndexRecord record = fusCrucialIndexRecordDAO.getFusCrucialIndexRecordByKey(request.getIndexId());
            if (CommonUtils.isNotEmpty(record)) {
                Long count = diseaseSpeciesRelateDAO.getCountByIndexId(request.getIndexId());
                if (count == null || count < 1L) {
                    fusCrucialIndexRecordDAO.deleteByIndexId(request.getIndexId());
                    List<FusIndexResult> results = fusIndexResultDAO.queryFusIndexResultList(record.getIndexId());
                    if (CommonUtils.isNotEmpty(results)) {
                        fusIndexResultDAO.deleteFusIndexResultIndexId(request.getIndexId());
                    }
                } else {//指标在使用删除
                    throw new ControllerException("该关联指标信息已经在使用中");
                }
            } else {
                throw new ControllerException("没有关联指标id相关的记录");
            }
        } else {
            throw new ControllerException("关联指标id不能为空");
        }
    }

    /**
     * 启禁用关联指标
     *
     * @param request
     * @throws ControllerException
     */
    @Override
    public void disableCrucialIndex(DeleteCrucialIndexRequest request) throws ControllerException {
        if (CommonUtils.isEmpty(request.getIndexId())) {
            throw new ControllerException("指标id不能为空");
        }
        if (CommonUtils.isEmpty(request.getStatus())) {
            throw new ControllerException("指标状态不能为空");
        }
        fusCrucialIndexRecordDAO.updateCrucialIndexStatus(request.getIndexId(), request.getStatus());
    }

    /**
     * @Description: 获取检验结果指标
     * @Author: zhaorb
     * @Date: 2020/7/20 14:17
     **/
    @Override
    public List<ExamineResultIndexResp> queryExamineResultIndex(QueryExamineResultIndexRequest request) {
        return indexHisService.queryExamineResultIndex(request).getData();
    }

    /**
     * @param request
     * @Description: 获取关联指标信息树信息
     * @Author: zhaorb
     * @Date: 2020/7/20 14:17
     */
    @Override
    @RpcService
    public List<IndexTreeResp> queryIndexTree(QueryCrucialIndexRequest request) throws ControllerException {
        List<IndexTreeResp> respList = new ArrayList<>();
        boolean check = false;
        boolean examine = false;
        if (CommonUtils.isEmpty(request.getIndexType())) {
            check = true;
            examine = true;
        } else {
            if (Constants.EXAMINE_TYPE.equals(request.getIndexType())) {
                examine = true;
            } else {
                check = true;
            }
        }
        try {
            if (examine) {
                //查询检验项目
                IndexTreeResp resp = new IndexTreeResp();
                resp.setIndexTreeName("检验项目");
                resp.setIndexTreeId("1");
                List<ItemIndexTree> treeList = queryItemIndexTree(request, Constants.EXAMINE_INDEX_TYPE, Constants.EXAMINE_TYPE);
                resp.setList(treeList);
                respList.add(resp);
            }
            if (check) {
                //查询检查项目
                IndexTreeResp respOther = new IndexTreeResp();
                respOther.setIndexTreeName("检查项目");
                respOther.setIndexTreeId("2");
                List<ItemIndexTree> treeList = queryItemIndexTree(request, Constants.CHECK_INDEX_TYPE, Constants.CHECK_TYPE);
                respOther.setList(treeList);
                respList.add(respOther);
            }
            return respList;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ControllerException("操作失败" + e.getMessage());
        }
    }

    /**
     * 同步lis的指标数据
     *
     * @throws ControllerException
     */
    @RpcService(timeout = 30)
    @Override
    public void syncCrucialIndexRecords(QueryCrucialRecordRequest request) throws ControllerException {
        if (CommonUtils.isEmpty(request.getIndexType())) {
            throw new ControllerException("指标类型不能为空");
        }
        if (CommonUtils.isEmpty(request.getOrganizationId())) {
            throw new ControllerException("机构标识不能为空");
        }
        try {
            //1.根据类型进行同步his指标数据
            String indexType = request.getIndexType();
            String[] splitIndexType = indexType.split(",");
            for (String split : splitIndexType) {
                List<InspectClassifyResponse> inspectClassifyList = new ArrayList<>();
                List<SimpleIndexResponse> sampleTypeList = new ArrayList<>();
                List<ExamClassifyResponse> examClassifyList = new ArrayList<>();
                List<CrucialResultNature> crucialResultNatureList = new ArrayList<>();
                //检验
                if (CrucialTypeEnum.INSPECT.getType().equals(split)) {
                    //设置同步检验数据每30秒一次
                    String key = request.getOrganizationId() + "_" + CrucialTypeEnum.INSPECT.getType();
                    if (CommonUtils.isNotEmpty(redisUtil.get(key))) {
                        throw new ControllerException(0, "同步检验数据较频繁，请稍后再试");
                    } else {
                        redisUtil.setnx(key, "30", 30);
                    }
                    //1.1 检验指标同步
                    handleInspectRecord(request);
                    //TODO 1.2检验分类同步
                    BaseResponse inspectClassify = crucialHisService.syncInspectClassifyRecordsHis(request);
                    if (CommonUtils.isNotEmpty(inspectClassify)) {
                        inspectClassifyList = (List<InspectClassifyResponse>) inspectClassify.getData();
                    }
                    //TODO 1.3检验样本同步
                    BaseResponse inspectSample = crucialHisService.syncInspectSampleRecordsHis(request);
                    if (CommonUtils.isNotEmpty(inspectSample)) {
                        sampleTypeList = (List<SimpleIndexResponse>) inspectSample.getData();
                    }
                    //TODO 1.4检验结果性质同步
                    BaseResponse crucialResult = crucialHisService.syncCrucialResultRecordHis(request);
                    if (CommonUtils.isNotEmpty(crucialResult)) {
                        crucialResultNatureList = (List<CrucialResultNature>) crucialResult.getData();
                    }

                } else if (CrucialTypeEnum.EXAM.getType().equals(split)) {
                    //检查分类同步
                    BaseResponse examClassify = crucialHisService.syncExamClassifyRecordsHis(request);
                    if (CommonUtils.isNotEmpty(examClassify)) {
                        examClassifyList = (List<ExamClassifyResponse>) examClassify.getData();
                        //TODO 检查分类中加入默认的检查指标数据
                        handleInspectIndexRecord(examClassifyList, request.getOrganizationId());
                    }
                } else if (CrucialTypeEnum.SIGN.getType().equals(split)) {
                    //体征信息同步
                    Dictionary dictionary = DictionaryController.instance().get(CrucialIndexCategoryEnum.SIGN_CRUCIAL.getId());
                    List<DictionaryItem> dicItems = dictionary.getSlice(null, 0, null);
                    for (DictionaryItem dicItem : dicItems) {
                        dealSignAndPathologyCrucialIndex(split, dicItem, request.getOrganizationId());
                    }
                } else if (CrucialTypeEnum.PATHOLOGY.getType().equals(split)) {
                    //病理信息同步
                    Dictionary dictionary = DictionaryController.instance().get(CrucialIndexCategoryEnum.PATHOLOGY.getId());
                    List<DictionaryItem> dicItems = dictionary.getSlice(null, 0, null);
                    for (DictionaryItem dicItem : dicItems) {
                        dealSignAndPathologyCrucialIndex(split, dicItem, request.getOrganizationId());
                    }
                }
                //3.保存字典分类信息
                String categoryId = addCrucialDictionaryCategory();
                //4.先把字典分类创建，然后再创建字典项
                for (CrucialIndexEnum value : CrucialIndexEnum.values()) {
                    addCrucialDictionary(categoryId, value.getId(), value.getName());
                }
                //5.遍历指标分类和样本类型信息，结果性质,保存到bbp字典
                addCrucialDictionaryItems(
                        inspectClassifyList,
                        examClassifyList,
                        sampleTypeList,
                        crucialResultNatureList);
            }
        } catch (ControllerException e) {
            log.info("同步lis的指标数据失败：{}", e.getMessage());
            throw new ControllerException("同步lis的指标数据失败：" + e.getMessage());
        }
    }

    /**
     * 处理检验数据从his同步逻辑
     *
     * @param request
     */
    private void handleInspectRecord(QueryCrucialRecordRequest request) {
        try {
            QueryCrucialRecordRequest requestValue = new QueryCrucialRecordRequest();
            BeanUtils.copyProperties(request, requestValue);
            for (int i = 1; i <= 10; i++) {
                requestValue.setPageNo(i);
                requestValue.setPageSize(100);
                BaseResponse inspectCrucial = crucialHisService.syncInspectCrucialRecordsHis(requestValue);
                List<CrucialIndexHisResponse> inspectCrucialList = (List<CrucialIndexHisResponse>) inspectCrucial.getData();
                if (CommonUtils.isNotEmpty(inspectCrucialList)) {
                    //2.遍历指标信息，如果已经在本地数据库存在，则不在进行保存，否则新增指标信息
                    for (CrucialIndexHisResponse indexHisResponse : inspectCrucialList) {
                        //根据指标code判断是否已经在数据库存在
                        FusCrucialIndexRecord fusCrucial = fusCrucialIndexRecordDAO.getFusCrucialIndexRecordByKey(indexHisResponse.getIndexId());
                        if (CommonUtils.isNotEmpty(fusCrucial)) {
                            continue;
                        }
                        fusCrucial = new FusCrucialIndexRecord();
                        BeanUtils.copyProperties(indexHisResponse, fusCrucial);
                        fusCrucial.setIndexStatus("1");
                        fusCrucial.setCreateTime(new Date());
                        fusCrucial.setModifyDt(new Date());
                        fusCrucialIndexRecordDAO.save(fusCrucial);
                    }
                }
            }
        } catch (ControllerException e) {
            e.printStackTrace();
        }
    }

    private void dealSignAndPathologyCrucialIndex(String split, DictionaryItem dicItem, String organizationId) {
        Long count = fusCrucialIndexRecordDAO.getCrucialIndexRecordByIndexName(dicItem.getText());
        if (count > 0) {
            return;
        }
        FusCrucialIndexRecord fusCrucial = new FusCrucialIndexRecord();
        fusCrucial.setIndexId(KeyGenerator.randomGenerate());
        fusCrucial.setIndexType(split);
        fusCrucial.setIndexCode(dicItem.getKey());
        fusCrucial.setIndexName(dicItem.getText());
        fusCrucial.setOrganizationId(organizationId);
        fusCrucial.setPinyinCode(PinyinHelper.getShortPinyin(dicItem.getText()));
        fusCrucial.setIndexStatus("1");
        Organization organization = organizationRpcService.getOrgDetailByOrgCode(organizationId);
        fusCrucial.setOrganizationName(organization.getFullName());
        fusCrucial.setCreateTime(new Date());
        fusCrucial.setModifyDt(new Date());
        fusCrucialIndexRecordDAO.save(fusCrucial);
    }

    /**
     * 保存检查默认指标数据
     *
     * @param examClassifyList
     * @param organizationId
     */
    private void handleInspectIndexRecord(List<ExamClassifyResponse> examClassifyList, String organizationId) {
        for (ExamClassifyResponse classifyResponse : examClassifyList) {
            for (InspectIndexEnum value : InspectIndexEnum.values()) {
                String type = CrucialTypeEnum.EXAM.getType();
                FusCrucialIndexRecord record = fusCrucialIndexRecordDAO.getFusCrucialIndexRecordByInspect(
                        type, value.getCode(), classifyResponse.getExamTypeCode());
                if (CommonUtils.isEmpty(record)) {
                    FusCrucialIndexRecord fusCrucial = new FusCrucialIndexRecord();
                    fusCrucial.setIndexId(KeyGenerator.randomGenerate());
                    fusCrucial.setIndexType(type);
                    fusCrucial.setIndexCode(value.getCode());
                    fusCrucial.setIndexName(value.getName());
                    fusCrucial.setOrganizationId(organizationId);
                    fusCrucial.setIndexStatus("1");
                    fusCrucial.setIndexClassifyId(classifyResponse.getExamTypeCode());
                    fusCrucial.setIndexClassifyName(classifyResponse.getExamTypeName());
                    Organization organization = organizationRpcService.getOrgDetailByOrgCode(organizationId);
                    fusCrucial.setOrganizationName(organization.getFullName());
                    fusCrucial.setCreateTime(new Date());
                    fusCrucial.setModifyDt(new Date());
                    //设置默认内置指标
                    fusCrucial.setIndexDefault("1");
                    fusCrucialIndexRecordDAO.save(fusCrucial);
                }
            }
        }
    }

    /**
     * 创建字典分类
     *
     * @return
     */
    private String addCrucialDictionaryCategory() throws ControllerException {
        String categoryId = "";
        DictionaryCategoryEntity categoryEntity = new DictionaryCategoryEntity();
        try {
            //字典分类已经存在则不在进行新增
            categoryId = redisUtil.get("categoryId");
            if (CommonUtils.isEmpty(categoryId)) {
                categoryEntity.setCd(CrucialIndexCategoryEnum.CRUCIAL_CATEGORY.getCode());
                categoryEntity.setNa(CrucialIndexCategoryEnum.CRUCIAL_CATEGORY.getName());
                categoryEntity.setPy(PinyinHelper.getShortPinyin(CrucialIndexCategoryEnum.CRUCIAL_CATEGORY.getName()));
                categoryEntity.setWb(WBConverter.getWBCode(CrucialIndexCategoryEnum.CRUCIAL_CATEGORY.getName()));
                categoryEntity.setZj(PinyinHelper.getShortPinyin(CrucialIndexCategoryEnum.CRUCIAL_CATEGORY.getName()));
                JSONResponseBean createDicCa = ServiceAdapter.invokeWithJsonBytes("bbp.dicConfig", "createDicCa", categoryEntity);
                if (CommonUtils.isNotEmpty(createDicCa.getBody())) {
                    Map<String, String> mapValue = (Map<String, String>) createDicCa.getBody();
                    categoryId = mapValue.get("id");
                }
                redisUtil.set("categoryId", categoryId);
            }
            return categoryId;
        } catch (Exception e) {
            log.info("创建字典分类失败：{}", e.getMessage());
            throw new ControllerException("创建字典分类失败：" + e.getMessage());
        }
    }

    /**
     * 新建字典项
     *
     * @param id
     * @param name
     */
    private void addCrucialDictionary(String categoryId, String id, String name) throws ControllerException {
        try {
            //判断该字典是否已经存在
            String tenantId = (String) ContextUtils.get("$tenantId");
            JSONResponseBean getDictionary = ServiceAdapter.invokeWithJsonBytes("bbp.dicConfig", "getDictionary", id + "@" + tenantId);
            if (CommonUtils.isEmpty(getDictionary.getBody())) {
                Map<String, Object> requestMap = new HashMap<>();
                //字典编码
                requestMap.put("id", id);
                //字典编码
                requestMap.put("cd", id);
                //字典名称
                requestMap.put("na", name);
                //字典分类
                requestMap.put("dicCategoryId", categoryId);
                //字典类型
                requestMap.put("dicType", "1");
                //字典等级
                requestMap.put("dicLevel", "1");
                //字典层级
                requestMap.put("storageType", "0");
                //是否公开
                requestMap.put("public", "true");
                //处理类型
                requestMap.put("usageType", "2");
                //字典描述
                requestMap.put("des", name);
                //新增字典bl_use.dic
                ServiceAdapter.invokeWithJsonBytes("bbp.dicConfig", "createDic", requestMap);
            }
        } catch (Exception e) {
            log.info("新建字典失败：{}", e.getMessage());
            throw new ControllerException("新建字典失败: " + e.getMessage());
        }
    }

    /**
     * 新增字典项
     *
     * @param indexClassifyResponses
     * @param simpleIndexResponses
     * @throws ControllerException
     */
    private void addCrucialDictionaryItems(
            List<InspectClassifyResponse> indexClassifyResponses,
            List<ExamClassifyResponse> examClassifyList,
            List<SimpleIndexResponse> simpleIndexResponses,
            List<CrucialResultNature> crucialResultNatures) throws ControllerException {
        try {
            String dId = "";
            String tenantId = (String) ContextUtils.get("$tenantId");
            if (CommonUtils.isNotEmpty(indexClassifyResponses)) {
                //新增字典项 分类为检验
                for (InspectClassifyResponse index : indexClassifyResponses) {
                    dId = CrucialIndexEnum.CRUCIAL_INSPECT_TYPE.getId();
                    createDictionaryItem(
                            dId + "@" + tenantId,
                            index.getIndexClassifyCode(),
                            index.getIndexClassifyName(),
                            null);
                }
                //更新字典缓存
                DictionaryController.instance().getUpdater().reload(dId + "@" + tenantId);
            }
            if (CommonUtils.isNotEmpty(examClassifyList)) {
                //新增字典项 分类为检查
                for (ExamClassifyResponse index : examClassifyList) {
                    dId = CrucialIndexEnum.CRUCIAL_CHECK_TYPE.getId();
                    createDictionaryItem(
                            dId + "@" + tenantId,
                            index.getExamTypeCode(),
                            index.getExamTypeName(),
                            null);
                }
                //更新字典缓存
                DictionaryController.instance().getUpdater().reload(dId + "@" + tenantId);
            }
            if (CommonUtils.isNotEmpty(simpleIndexResponses)) {
                //新增字典项 样本类型
                dId = CrucialIndexEnum.SAMPLE_TYPE.getId();
                for (SimpleIndexResponse simple : simpleIndexResponses) {
                    createDictionaryItem(
                            dId + "@" + tenantId,
                            simple.getSimpleType(),
                            simple.getSimpleName(),
                            null);
                }
                //更新字典缓存
                DictionaryController.instance().getUpdater().reload(dId + "@" + tenantId);
            }
            if (CommonUtils.isNotEmpty(crucialResultNatures)) {
                //新增字典项 结果性质
                dId = CrucialIndexEnum.RESULT_NATURE.getId();
                for (CrucialResultNature crucial : crucialResultNatures) {
                    DictionaryItemEntity dictionaryItem = createDictionaryItem(
                            dId + "@" + tenantId,
                            crucial.getResultNatureCode(),
                            crucial.getResultNatureValue(),
                            null);
                    //存在字典项子节点
                    if (CommonUtils.isNotEmpty(crucial.getResultNatureList())) {
                        List<CrucialResultNature> childResultNature = crucial.getResultNatureList();
                        for (CrucialResultNature nature : childResultNature) {
                            if (CommonUtils.isNotEmpty(dictionaryItem)) {
                                createDictionaryItem(
                                        dId + "@" + tenantId,
                                        nature.getResultNatureCode(),
                                        nature.getResultNatureValue(),
                                        dictionaryItem.getCd());
                            }
                        }
                    }
                }
                //更新字典缓存
                DictionaryController.instance().getUpdater().reload(dId + "@" + tenantId);
            }
        } catch (Exception e) {
            log.info("新建字典项失败：{}", e.getMessage());
            throw new ControllerException("新建字典项失败: " + e.getMessage());
        }
    }

    /**
     * 创建字典项
     *
     * @param dTenantId
     * @param code
     * @param name
     * @param parentId
     * @throws Exception
     */
    private DictionaryItemEntity createDictionaryItem(String dTenantId, String code, String name, String parentId) throws Exception {
        Dictionary dic = DictionaryController.instance().get(dTenantId);
        DictionaryItemEntity item = (DictionaryItemEntity) dic.getItem(code);
        if (CommonUtils.isEmpty(item)) {
            //不存在则新增
            DictionaryItemEntity dictionaryItem = new DictionaryItemEntity();
            dictionaryItem.setDicId(dTenantId);
            dictionaryItem.setCd(code);
            dictionaryItem.setNa(name);
            dictionaryItem.setLeaf(true);
            if (StringUtils.isNotEmpty(parentId)) {
                dictionaryItem.setParentId(parentId);
            }
            DictionaryItemEntity createDicItems = (DictionaryItemEntity) ServiceAdapter.invoke("bbp.dicConfig", "createDicItems", dictionaryItem);
            return createDicItems;
        } else {
            Map<String, Object> updateItem = new HashMap<>();
            updateItem.put("id", item.getId());
            updateItem.put("active", item.isActive());
            ServiceAdapter.invoke("bbp.dicConfig", "updateDicItem", updateItem);
        }
        return null;
    }


    private List<ItemIndexTree> queryItemIndexTree(QueryCrucialIndexRequest request, String indexType, String type) {
        List<ItemIndexTree> treeList = new ArrayList<>();
        QueryIndexTypeReq req = new QueryIndexTypeReq();
        req.setDictCode(indexType);
        List<IndexTypeParameterResp> list = indexHisService.getIndexTypeParameter(req).getData();
        for (IndexTypeParameterResp dictionary : list) {
            String indexClassifyId = dictionary.getDictId();
            String title = dictionary.getDictName();
            ItemIndexTree tree = new ItemIndexTree();
            tree.setIndexTreeName(title);
            treeList.add(tree);
            List<FusCrucialIndexRecord> records;
            if (CommonUtils.isNotEmpty(request.getOrganizationId())) {
                records = fusCrucialIndexRecordDAO.queryRecordList(
                        request.getOrganizationId(), indexClassifyId, type);
            } else {
                records = fusCrucialIndexRecordDAO.queryRecordList2(indexClassifyId, type);
            }
            List<IndexResponse> indexResponses = new ArrayList<>();
            for (FusCrucialIndexRecord record : records) {
                IndexResponse response = new IndexResponse();
                BeanUtils.copyProperties(record, response);
                response.setIndexTreeName(record.getIndexName());
                //查询指标结果
                List<FusIndexResult> results = fusIndexResultDAO.queryFusIndexResultList(record.getIndexId());
                response.setResultList(results);
                indexResponses.add(response);
            }
            tree.setList(indexResponses);
        }
        return treeList;
    }
}
